import mysql from 'mysql2'
import { createForm } from './form.js'
import { createViewTemplate,crateViewListTemplate } from './template.js'
import { createValidate } from './validate.js'
import { createRestful } from './restful.js'
import { createRouter, appendTopRouter } from './router.js'
import { createStore } from './store.js'
import { createComposable } from './composable.js'
import fs from 'fs'
export class Db {
  #conn
  #whereStr
  #orderStr
  /**
   *
   * @param {string} host
   * @param {string} user
   * @param {string} password
   * @param {string} database
   * @param {string} port
   */
  constructor (host, user, password, database, port) {
    this.#conn = mysql.createConnection({
      host: host,
      user: user,
      password: password,
      database: database,
      port:port
    })
    this.#conn.connect(function(err){
      if(!err){
        console.log("数据库连接成功")
      }else{
        console.log("数据库连接失败",err)
      }
    })
  }

  // db close
  end = () => {
    this.#conn.end()
  }

  query = (queryStr) => {
    const promise = new Promise((resolve, reject) => {
      this.#conn.query(queryStr, function (_err, rows) {
        resolve(rows)
      })
    })
    return promise
  }

  clean = () => {
    this.#whereStr = ''
    this.#orderStr = ''
  }

  /**
   * db select
   * @param {string} tablename
   * @param {object} fields select fields
   * @returns {promise}
   */
  select = (tableName, fields = []) => {
    const selFields = fields.length ? fields.join(',') : '*'
    let queryStr = `
    SELECT ${selFields} FROM ${tableName}
    `
    if (this.#whereStr !== '') {
      queryStr += ` where ${this.#whereStr}`
    }
    return this.query(queryStr)
  }

  /**
   * insert
   * @param {string} tableName
   * @param {object} data insert data
   */
  insert = (tableName, data) => {
    const columnFields = Object.keys(data)
    let fields = '('
    let values = '('
    const length = columnFields.length
    for (let i = 0; i < length; i++) {
      const field = columnFields[i]
      fields += `\`${field}\``
      values += `'${data[field]}'`
      if (i !== length - 1) {
        fields += ','
        values += ','
      }
      fields += ')'
      values += ')'
    }
    const queryStr = `
    INSERT INTO ${tableName} ${fields} VALUES ${values}
    `
    return this.query(queryStr)
  }

  /**
   * insert multi data
   * @param {string} tableName
   * @param {array} dataArr
   */
  inserts = (tableName, dataArr) => {
    let fields = '('
    let values = '('
    const arrLen = dataArr.length
    // field
    const keys = Object.keys(dataArr[0])
    const length = keys.length
    for (let i = 0; i < length; i++) {
      const field = keys[i]
      fields += `\`${field}\``
      values += `'${dataArr[0][field]}'`
      if (i !== length - 1) {
        fields += ','
        values += ','
      }
    }
    values += ')'
    fields += ')'
    // values
    for (let index = 1; index < arrLen; index++) {
      values += ',('
      const keys = Object.keys(dataArr[index])
      const length = keys.length
      for (let i = 0; i < length; i++) {
        const field = keys[i]
        values += `'${dataArr[index][field]}'`
        if (i !== length - 1) {
          values += ','
        }
      }
      values += ')'
    }
    const queryStr = `
    INSERT INTO ${tableName} ${fields} VALUES ${values}`
    return this.query(queryStr)
  }

  // where
  whereIn = (whereInObj) => {
    // TD
  }

  /**
   *  db where
   * @param {object} whereObj
   * @returns  this
   */
  where = (whereObj) => {
    // TD
    const keys = Object.keys(whereObj)
    const length = keys.length
    let str = ''
    for (let i = 0; i < length; i++) {
      str += `\`${keys[i]}\`= '${whereObj[keys[i]]}'`
      if (i !== length - 1) {
        str += ' and '
      }
    }
    this.#whereStr = this.#whereStr === '' ? str : `${this.#whereStr} and ${str}`
    return this
  }

  order = () => {
    // TD
  }
}

// const listColumns = []
const createListModel = (tableName, callback = () => { }) => {
  // if (listColumns.length) {
  //   callback.apply(listColumns)
  //   return
  // }
  fs.readFile('src/scripts/config.json', 'utf8', (err, data) => {
    if (err) throw err
    const config = JSON.parse(data)
    const fileName = `${config.dbFolder}/list/${tableName}.json`
    if (!fs.existsSync(fileName)) {
      // model不存在 创建
      console.log(`============ no ${tableName} list model and please create ============ `)
    } else {
        const listColumns = []
        fs.readFile(fileName, 'utf-8', (err, data) => {
          const rows = JSON.parse(data)
          if (rows && rows.length > 0) {
            rows.forEach((item) => {
              if (config.db.exceptedFields.split(',').findIndex((except) => except === item.columnName) === -1 && item.columnName !== `${tableName}_id`) {
                // 去掉表_id 和其他字段
                listColumns.push(item)
              }
            })
            callback.call(this,listColumns)
          }
        })
      }
    })

}




export function tableModel (tableName, op = '-all') {
  fs.readFile('src/scripts/config.json', 'utf8', (err, data) => {
    if (err) throw err
    const config = JSON.parse(data)
    const fileName = `${config.dbFolder}/model/${tableName}.json`
    if (!fs.existsSync(fileName)) {
      // model不存在 创建
      console.log(`============ no ${tableName} model and please create ============ `)
    }else{
      fs.readFile(fileName, 'utf-8', (err, data) => {
        const rows =  JSON.parse(data)
        let tableDesc = ''
        if (rows && rows.length > 0) {
          const columns = []
          rows.forEach((item) => {
            if (item.columnName === 'id') {
              tableDesc = item.columnComment
            }
            if ( config.db.exceptedFields.split(',').findIndex((except) => except === item.columnName) === -1 && item.columnName !== `${tableName}_id`) {
              // 去掉表_id 和其他字段
              columns.push(item)
            }

          })
          if (columns.length > 0) {
            // 默认加入keywords
            // columns.push({columnName:'keywords',columnComment:'关键词|ignored',reflectColumnName:'keywords',columnType:"varchar(100)",dataType:'varchar',columnDefault:''})
            switch (op) {
              case '-form':
                createForm(columns, tableName) // 创建model form
                // createListModel(tableName, op)
                break
              case '-view':
                createViewTemplate(columns, tableName, 'add')
                createViewTemplate(columns, tableName, 'update')
                createViewTemplate(columns, tableName, 'detail')
                createListModel(tableName, (listColumns) => {
                  crateViewListTemplate(listColumns, tableName)
                })
                // crateViewListTemplate(columns, tableName)

                break
              case '-validate':
                createValidate(columns, tableName)
                break
              case '-restful':
                createRestful(tableName)
                break
              case '-router':
                createRouter(tableName, tableDesc)
                appendTopRouter(tableName)
                break
              case '-store':
                createStore(tableName)
                createListModel(tableName, (listColumns) => {
                  createComposable(listColumns, tableName )
                })
                break
              case '-all':
                createForm(columns, tableName)
                createListModel(tableName, (listColumns) => {
                  createComposable(listColumns, tableName)
                  crateViewListTemplate(listColumns, tableName)
                })
                createViewTemplate(columns, tableName, 'add')
                createViewTemplate(columns, tableName, 'update')
                createViewTemplate(columns, tableName, 'detail')
                // createListModel(tableName,'-all')
                // crateViewListTemplate(columns, tableName)
                createValidate(columns, tableName)
                createRestful(tableName)
                createRouter(tableName, tableDesc)
                appendTopRouter(tableName)
                createStore(tableName)
                // appendTopStore(tableName)
            }
          } else {
            console.log('============ no effective fields or the table is not existed ===============')
          }
        }
      })

    }
  })
}
